package com.khoayang.littlefighterchaos.game;

import java.io.InputStream;
//import java.security.CodeSigner;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.cocos2d.nodes.CCSprite;
import org.cocos2d.types.CGSize;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.khoayang.littlefighterchaos.game.GamePad.KEY;

import android.content.Context;
//import android.content.Context;
import android.content.res.AssetManager;
//import android.inputmethodservice.Keyboard;

public class CharacterFactory {
	private ArrayList<CharacterGame> _AllCharacter;
	private Context _Context;
	private static CharacterFactory _Instance;
	
	private CharacterFactory(Context context)
	{
		_Context = context;
	}
	
	public static CharacterFactory getInstance(Context context)
	{
		if(_Instance == null)
			_Instance = new CharacterFactory(context);
		return _Instance;
	}
	
	public CharacterGame cloneCharacterByName(String name){
		if(name.compareTo("") ==0)
			return null;
		CharacterGame character = null;
		for(int i=0; i<get_AllCharacter().size(); i++)
		{
			if(get_AllCharacter().get(i).get_State().get_Name().compareTo(name) == 0){
				try {
					character = get_AllCharacter().get(i).clone();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			}
		}
		return character;
	}
	
	public void initAllCharacter(AssetManager assetManager, String filename)
	{
		_AllCharacter = new ArrayList<CharacterGame>();
		try{
			InputStream is = assetManager.open(filename);
			DocumentBuilder docBulder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document doc = docBulder.parse(is);
			NodeList characterList = doc.getElementsByTagName("Character");
			for (int i=0; i<characterList.getLength(); i++) {
				Node characterNode = characterList.item(i);
				CharacterGame character = getCharacterFromXmlNode(characterNode);
				get_AllCharacter().add(character);
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}

	private CharacterGame getCharacterFromXmlNode(Node characterNode) {
		CharacterGame character = new CharacterGame();
		State state = new State();
		character.set_State(state);
		for(int j=0; j<characterNode.getChildNodes().getLength(); j++){
			Node nodeTemp = characterNode.getChildNodes().item(j);
			if(nodeTemp.getNodeName().compareTo("Name") == 0)
			{
				state.set_Name(nodeTemp.getTextContent());
			}else if(nodeTemp.getNodeName().compareTo("Sprite") == 0){
				character.set_Sprite(CCSprite.sprite(nodeTemp.getTextContent()));
			}else if(nodeTemp.getNodeName().compareTo("BarHP") == 0){
				Bar bar = new Bar();
				bar.loadBarFromXMLNode(nodeTemp);
				character.set_HPBar(bar);
			}else if(nodeTemp.getNodeName().compareTo("BarMP") == 0){
				Bar bar = new Bar();
				bar.loadBarFromXMLNode(nodeTemp);
				character.set_MPBar(bar);
			}else if(nodeTemp.getNodeName().compareTo("HP") == 0){
				character.set_HP(Float.parseFloat(nodeTemp.getTextContent()));
			}else if(nodeTemp.getNodeName().compareTo("MP") == 0){
				character.set_MP(Float.parseFloat(nodeTemp.getTextContent()));
			}else if(nodeTemp.getNodeName().compareTo("AutoMPRegen") == 0){
				state.set_AutoMPRegen(Float.parseFloat(nodeTemp.getTextContent()));
			}else if(nodeTemp.getNodeName().compareTo("Size") == 0){
				float w = Integer.parseInt(nodeTemp.getAttributes().getNamedItem("width").getNodeValue());
				float h = Integer.parseInt(nodeTemp.getAttributes().getNamedItem("height").getNodeValue());
				CGSize size = CGSize.make(w, h);
				character.set_Size(size);
			}else if(nodeTemp.getNodeName().compareTo("Skills") == 0){
				getSkillsFromNode(nodeTemp, state);
				character.set_State(state);
			}else if(nodeTemp.getNodeName().compareTo("Commands") == 0){
				ArrayList<Command> commands = getCommandsFromNode(nodeTemp);
				state.set_Commands(commands);
			}
		}
		return character;
	}

	private ArrayList<Command> getCommandsFromNode(Node node) {
		ArrayList<Command> commands = new ArrayList<Command>();
		for(int i=0; i<node.getChildNodes().getLength(); i++){
			Node nodeTemp = node.getChildNodes().item(i);
			String nodeName = nodeTemp.getNodeName();
			if(nodeName.compareTo("Command") == 0){
				Command command = getCommandFromNode(nodeTemp);
				commands.add(command);
			}
		}
		return commands;
	}

	private Command getCommandFromNode(Node node) {
		Command command = new Command();
		for(int i=0; i<node.getChildNodes().getLength(); i++){
			Node nodeTemp = node.getChildNodes().item(i);
			String nodeName = nodeTemp.getNodeName();
			if(nodeName.compareTo("Keys") == 0){
				String[] keys = nodeTemp.getTextContent().split(" ");
				ArrayList<KEY> enumKeys = getEnumKeys(keys);
				command.set_Keys(enumKeys);
			}else if(nodeName.compareTo("SkillName") == 0){
				command.set_CommandNames(nodeTemp.getTextContent());
			}
		}
		return command;
	}

	private ArrayList<KEY> getEnumKeys(String[] keys) {
		ArrayList<KEY> enumKeys = new ArrayList<GamePad.KEY>();
		for(int i=0; i<keys.length; i++){
			KEY enumKey = KEY.LEFT;
			String key = keys[i];
			if(key.compareTo("LEFT") == 0){
				enumKey = KEY.LEFT;
			}else if(key.compareTo("RIGHT") == 0){
				enumKey = KEY.RIGHT;
			}else if(key.compareTo("UP") == 0){
				enumKey = KEY.UP;
			}else if(key.compareTo("DOWN") == 0){
				enumKey = KEY.DOWN;
			}else if(key.compareTo("ATTACK") == 0){
				enumKey = KEY.ATTACK;
			}else if(key.compareTo("DEFEND") == 0){
				enumKey = KEY.DEFEND;
			}else if(key.compareTo("JUMP") == 0){
				enumKey = KEY.JUMP;
			}
			enumKeys.add(enumKey);
		}
		return enumKeys;
	}

	private void getSkillsFromNode(Node node, State state) {
		ArrayList<BaseSkill> skills = new ArrayList<BaseSkill>();
		for(int i=0; i<node.getChildNodes().getLength(); i++){
			Node nodeTemp = node.getChildNodes().item(i);
			String nodeName = nodeTemp.getNodeName();
			if(nodeName.compareTo("Skill") == 0){
				for(int j=0; j<nodeTemp.getChildNodes().getLength(); j++){
					String nodeNameTemp = nodeTemp.getChildNodes().item(j).getNodeName();
					if(nodeNameTemp.compareTo("Type") == 0){
						BaseSkill skill = null;
						SkillFactory skillFactory = new SkillFactory();
						skill = skillFactory.getSkillByName(nodeTemp.getChildNodes().item(j).getTextContent(), _Context);
						skill.readSkill(nodeTemp);
						skills.add(skill);
						break;
					}
				}
			}
		}
		state.set_SkillList(skills);
	}

	public ArrayList<CharacterGame> get_AllCharacter() {
		return _AllCharacter;
	}

	public State cloneStateByNameCharacter(String newFormName) {
		for(int i=0; i<_AllCharacter.size(); i++){
			CharacterGame character = _AllCharacter.get(i);
			if(character.get_State().get_Name().compareTo(newFormName) == 0){
				return character.get_State().clone(); 
			}
		}
		return null;
	}
}
